//! Schema解析器模块
//! 
//! 提供自动推断表结构和类型映射功能

use crate::error::{DataForgeError, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;

/// 数据类型
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum DataType {
    /// 字符串类型
    String { max_length: Option<usize> },
    /// 整数类型
    Integer { min: Option<i64>, max: Option<i64> },
    /// 浮点数类型
    Float { min: Option<f64>, max: Option<f64>, precision: Option<usize> },
    /// 布尔类型
    Boolean,
    /// 日期时间类型
    DateTime { format: Option<String> },
    /// 日期类型
    Date { format: Option<String> },
    /// 时间类型
    Time { format: Option<String> },
    /// UUID类型
    Uuid,
    /// 邮箱类型
    Email,
    /// 电话号码类型
    Phone { country: Option<String> },
    /// URL类型
    Url,
    /// JSON类型
    Json,
    /// 数组类型
    Array { item_type: Box<DataType>, min_items: Option<usize>, max_items: Option<usize> },
    /// 对象类型
    Object { fields: HashMap<String, FieldSchema> },
    /// 枚举类型
    Enum { values: Vec<String> },
    /// 自定义类型
    Custom { type_name: String, generator: String },
}

/// 字段约束
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FieldConstraints {
    /// 是否可为空
    pub nullable: bool,
    /// 是否唯一
    pub unique: bool,
    /// 默认值
    pub default: Option<serde_json::Value>,
    /// 正则表达式约束
    pub pattern: Option<String>,
    /// 最小值
    pub min: Option<serde_json::Value>,
    /// 最大值
    pub max: Option<serde_json::Value>,
}

impl Default for FieldConstraints {
    fn default() -> Self {
        Self {
            nullable: false,
            unique: false,
            default: None,
            pattern: None,
            min: None,
            max: None,
        }
    }
}

/// 字段生成器类型
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum FieldGeneratorType {
    /// 默认生成器（基于数据类型自动选择）
    Default,
    /// 自定义生成器（指定生成器名称）
    Custom(String),
    /// 随机字符串
    RandomString,
    /// 随机整数
    RandomInteger,
    /// 随机浮点数
    RandomFloat,
    /// 随机布尔值
    RandomBoolean,
    /// 当前时间戳
    CurrentTimestamp,
    /// 随机日期
    RandomDate,
    /// 随机日期时间
    RandomDateTime,
    /// 随机邮箱
    RandomEmail,
    /// 随机电话号码
    RandomPhone,
    /// 随机URL
    RandomUrl,
    /// UUID
    Uuid,
    /// 姓名
    Name,
    /// 公司名称
    CompanyName,
    /// 地址
    Address,
    /// 产品名称
    ProductName,
    /// 订单状态
    OrderStatus,
}

/// 字段Schema
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FieldSchema {
    /// 字段名
    pub name: String,
    /// 数据类型
    pub data_type: DataType,
    /// 约束条件
    pub constraints: FieldConstraints,
    /// 描述
    pub description: Option<String>,
    /// 生成器配置
    pub generator_config: Option<HashMap<String, serde_json::Value>>,
    /// 字段生成器类型
    pub generator_type: Option<FieldGeneratorType>,
}

impl FieldSchema {
    /// 创建新的字段Schema
    pub fn new(name: String, data_type: DataType) -> Self {
        Self {
            name,
            data_type,
            constraints: FieldConstraints::default(),
            description: None,
            generator_config: None,
            generator_type: None,
        }
    }
    
    /// 设置字段生成器类型
    pub fn with_generator_type(mut self, generator_type: FieldGeneratorType) -> Self {
        self.generator_type = Some(generator_type);
        self
    }
    
    /// 设置字段约束
    pub fn with_constraints(mut self, constraints: FieldConstraints) -> Self {
        self.constraints = constraints;
        self
    }
    
    /// 设置字段描述
    pub fn with_description(mut self, description: String) -> Self {
        self.description = Some(description);
        self
    }
    
    /// 设置生成器配置
    pub fn with_generator_config(mut self, config: HashMap<String, serde_json::Value>) -> Self {
        self.generator_config = Some(config);
        self
    }
}

/// 表Schema
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct TableSchema {
    /// 表名
    pub name: String,
    /// 字段列表
    pub fields: Vec<FieldSchema>,
    /// 主键字段
    pub primary_key: Option<Vec<String>>,
    /// 索引定义
    pub indexes: Vec<IndexSchema>,
    /// 表描述
    pub description: Option<String>,
}

impl TableSchema {
    /// 创建新的表Schema
    pub fn new(name: String) -> Self {
        Self {
            name,
            fields: Vec::new(),
            primary_key: None,
            indexes: Vec::new(),
            description: None,
        }
    }
    
    /// 添加字段
    pub fn add_field(&mut self, field: FieldSchema) {
        self.fields.push(field);
    }
    
    /// 设置主键
    pub fn with_primary_key(mut self, primary_key: Vec<String>) -> Self {
        self.primary_key = Some(primary_key);
        self
    }
    
    /// 添加索引
    pub fn add_index(&mut self, index: IndexSchema) {
        self.indexes.push(index);
    }
    
    /// 设置表描述
    pub fn with_description(mut self, description: String) -> Self {
        self.description = Some(description);
        self
    }
}

/// 索引Schema
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IndexSchema {
    /// 索引名
    pub name: String,
    /// 索引字段
    pub fields: Vec<String>,
    /// 是否唯一索引
    pub unique: bool,
}

/// Schema解析器
pub struct SchemaParser {
    /// 类型映射规则
    type_mappings: HashMap<String, DataType>,
    /// 模式识别规则
    pattern_rules: Vec<PatternRule>,
}

/// 模式识别规则
#[derive(Debug, Clone)]
pub struct PatternRule {
    /// 字段名模式
    pub field_pattern: regex::Regex,
    /// 对应的数据类型
    pub data_type: DataType,
    /// 优先级
    pub priority: u32,
}

impl SchemaParser {
    /// 创建新的Schema解析器
    pub fn new() -> Self {
        let mut parser = Self {
            type_mappings: HashMap::new(),
            pattern_rules: Vec::new(),
        };
        
        parser.init_default_mappings();
        parser.init_default_patterns();
        parser
    }

    /// 初始化默认类型映射
    fn init_default_mappings(&mut self) {
        // 基础类型映射
        self.type_mappings.insert("string".to_string(), DataType::String { max_length: Some(255) });
        self.type_mappings.insert("text".to_string(), DataType::String { max_length: None });
        self.type_mappings.insert("varchar".to_string(), DataType::String { max_length: Some(255) });
        self.type_mappings.insert("char".to_string(), DataType::String { max_length: Some(1) });
        
        self.type_mappings.insert("int".to_string(), DataType::Integer { min: None, max: None });
        self.type_mappings.insert("integer".to_string(), DataType::Integer { min: None, max: None });
        self.type_mappings.insert("bigint".to_string(), DataType::Integer { min: None, max: None });
        self.type_mappings.insert("smallint".to_string(), DataType::Integer { min: Some(-32768), max: Some(32767) });
        
        self.type_mappings.insert("float".to_string(), DataType::Float { min: None, max: None, precision: None });
        self.type_mappings.insert("double".to_string(), DataType::Float { min: None, max: None, precision: None });
        self.type_mappings.insert("decimal".to_string(), DataType::Float { min: None, max: None, precision: Some(2) });
        
        self.type_mappings.insert("boolean".to_string(), DataType::Boolean);
        self.type_mappings.insert("bool".to_string(), DataType::Boolean);
        
        self.type_mappings.insert("datetime".to_string(), DataType::DateTime { format: None });
        self.type_mappings.insert("timestamp".to_string(), DataType::DateTime { format: None });
        self.type_mappings.insert("date".to_string(), DataType::Date { format: None });
        self.type_mappings.insert("time".to_string(), DataType::Time { format: None });
        
        self.type_mappings.insert("uuid".to_string(), DataType::Uuid);
        self.type_mappings.insert("json".to_string(), DataType::Json);
    }

    /// 初始化默认模式规则
    fn init_default_patterns(&mut self) {
        // ID字段
        if let Ok(regex) = regex::Regex::new(r"(?i)^.*id$") {
            self.pattern_rules.push(PatternRule {
                field_pattern: regex,
                data_type: DataType::Integer { min: Some(1), max: None },
                priority: 100,
            });
        }

        // UUID字段
        if let Ok(regex) = regex::Regex::new(r"(?i)^.*uuid$") {
            self.pattern_rules.push(PatternRule {
                field_pattern: regex,
                data_type: DataType::Uuid,
                priority: 90,
            });
        }

        // 邮箱字段
        if let Ok(regex) = regex::Regex::new(r"(?i)^.*(email|mail).*$") {
            self.pattern_rules.push(PatternRule {
                field_pattern: regex,
                data_type: DataType::Email,
                priority: 80,
            });
        }

        // 电话字段
        if let Ok(regex) = regex::Regex::new(r"(?i)^.*(phone|tel|mobile).*$") {
            self.pattern_rules.push(PatternRule {
                field_pattern: regex,
                data_type: DataType::Phone { country: Some("CN".to_string()) },
                priority: 80,
            });
        }

        // 姓名字段
        if let Ok(regex) = regex::Regex::new(r"(?i)^.*(name|username).*$") {
            self.pattern_rules.push(PatternRule {
                field_pattern: regex,
                data_type: DataType::String { max_length: Some(100) },
                priority: 70,
            });
        }

        // 时间字段
        if let Ok(regex) = regex::Regex::new(r"(?i)^.*(created_at|updated_at|timestamp).*$") {
            self.pattern_rules.push(PatternRule {
                field_pattern: regex,
                data_type: DataType::DateTime { format: None },
                priority: 75,
            });
        }

        // 地址字段
        if let Ok(regex) = regex::Regex::new(r"(?i)^.*(address|addr).*$") {
            self.pattern_rules.push(PatternRule {
                field_pattern: regex,
                data_type: DataType::String { max_length: Some(500) },
                priority: 60,
            });
        }
    }

    /// 从JSON Schema推断表结构
    pub fn infer_from_json(&self, json_schema: &serde_json::Value) -> Result<TableSchema> {
        match json_schema {
            serde_json::Value::Object(obj) => {
                let table_name = obj.get("title")
                    .and_then(|v| v.as_str())
                    .unwrap_or("generated_table")
                    .to_string();

                let mut fields = Vec::new();

                if let Some(properties) = obj.get("properties").and_then(|v| v.as_object()) {
                    for (field_name, field_schema) in properties {
                        let field = self.parse_field_schema(field_name, field_schema)?;
                        fields.push(field);
                    }
                }

                Ok(TableSchema {
                    name: table_name,
                    fields,
                    primary_key: None,
                    indexes: Vec::new(),
                    description: obj.get("description").and_then(|v| v.as_str()).map(|s| s.to_string()),
                })
            }
            _ => Err(DataForgeError::validation("Invalid JSON schema format")),
        }
    }

    /// 解析字段Schema
    fn parse_field_schema(&self, field_name: &str, schema: &serde_json::Value) -> Result<FieldSchema> {
        let data_type = self.infer_data_type(field_name, schema)?;
        
        let constraints = FieldConstraints {
            nullable: !schema.get("required").unwrap_or(&serde_json::Value::Bool(false)).as_bool().unwrap_or(false),
            unique: schema.get("unique").and_then(|v| v.as_bool()).unwrap_or(false),
            default: schema.get("default").cloned(),
            pattern: schema.get("pattern").and_then(|v| v.as_str()).map(|s| s.to_string()),
            min: schema.get("minimum").cloned(),
            max: schema.get("maximum").cloned(),
        };

        Ok(FieldSchema {
            name: field_name.to_string(),
            data_type,
            constraints,
            description: schema.get("description").and_then(|v| v.as_str()).map(|s| s.to_string()),
            generator_config: None,
            generator_type: None, // 默认使用自动推断的生成器类型
        })
    }

    /// 推断数据类型
    pub fn infer_data_type(&self, field_name: &str, schema: &serde_json::Value) -> Result<DataType> {
        // 首先使用模式匹配推断更具体的类型
        let mut best_match: Option<&PatternRule> = None;
        for rule in &self.pattern_rules {
            if rule.field_pattern.is_match(field_name) {
                if best_match.is_none() || rule.priority > best_match.unwrap().priority {
                    best_match = Some(rule);
                }
            }
        }

        if let Some(rule) = best_match {
            return Ok(rule.data_type.clone());
        }

        // 然后检查是否有明确的类型定义
        if let Some(type_str) = schema.get("type").and_then(|v| v.as_str()) {
            if let Some(data_type) = self.type_mappings.get(type_str) {
                return Ok(data_type.clone());
            }
        }

        // 默认为字符串类型
        Ok(DataType::String { max_length: Some(255) })
    }

    /// 从数据库表结构推断Schema
    pub fn infer_from_database_table(&self, table_info: &DatabaseTableInfo) -> Result<TableSchema> {
        let mut fields = Vec::new();

        for column in &table_info.columns {
            let data_type = self.map_database_type(&column.data_type)?;
            
            let constraints = FieldConstraints {
                nullable: column.nullable,
                unique: column.unique,
                default: column.default_value.clone(),
                pattern: None,
                min: None,
                max: None,
            };

            fields.push(FieldSchema {
                name: column.name.clone(),
                data_type,
                constraints,
                description: column.comment.clone(),
                generator_config: None,
                generator_type: None, // 默认使用自动推断的生成器类型
            });
        }

        Ok(TableSchema {
            name: table_info.name.clone(),
            fields,
            primary_key: Some(table_info.primary_key.clone()),
            indexes: table_info.indexes.iter().map(|idx| IndexSchema {
                name: idx.name.clone(),
                fields: idx.columns.clone(),
                unique: idx.unique,
            }).collect(),
            description: table_info.comment.clone(),
        })
    }

    /// 映射数据库类型到内部类型
    pub fn map_database_type(&self, db_type: &str) -> Result<DataType> {
        let normalized_type = db_type.to_lowercase();
        
        // 处理带参数的类型，如 VARCHAR(255)
        let base_type = if let Some(pos) = normalized_type.find('(') {
            &normalized_type[..pos]
        } else {
            &normalized_type
        };

        self.type_mappings.get(base_type)
            .cloned()
            .ok_or_else(|| DataForgeError::validation(&format!("Unsupported database type: {}", db_type)))
    }

    /// 添加自定义类型映射
    pub fn add_type_mapping(&mut self, db_type: String, data_type: DataType) {
        self.type_mappings.insert(db_type, data_type);
    }

    /// 添加模式规则
    pub fn add_pattern_rule(&mut self, pattern: &str, data_type: DataType, priority: u32) -> Result<()> {
        let regex = regex::Regex::new(pattern)
            .map_err(|e| DataForgeError::validation(&format!("Invalid regex pattern: {}", e)))?;
        
        self.pattern_rules.push(PatternRule {
            field_pattern: regex,
            data_type,
            priority,
        });

        // 按优先级排序
        self.pattern_rules.sort_by(|a, b| b.priority.cmp(&a.priority));
        
        Ok(())
    }
}

/// 数据库表信息
#[derive(Debug, Clone)]
pub struct DatabaseTableInfo {
    pub name: String,
    pub columns: Vec<DatabaseColumnInfo>,
    pub primary_key: Vec<String>,
    pub indexes: Vec<DatabaseIndexInfo>,
    pub comment: Option<String>,
}

/// 数据库列信息
#[derive(Debug, Clone)]
pub struct DatabaseColumnInfo {
    pub name: String,
    pub data_type: String,
    pub nullable: bool,
    pub unique: bool,
    pub default_value: Option<serde_json::Value>,
    pub comment: Option<String>,
}

/// 数据库索引信息
#[derive(Debug, Clone)]
pub struct DatabaseIndexInfo {
    pub name: String,
    pub columns: Vec<String>,
    pub unique: bool,
}

impl Default for SchemaParser {
    fn default() -> Self {
        Self::new()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;

    #[test]
    fn test_schema_parser_creation() {
        let parser = SchemaParser::new();
        assert!(!parser.type_mappings.is_empty());
        assert!(!parser.pattern_rules.is_empty());
    }

    #[test]
    fn test_infer_from_json() {
        let parser = SchemaParser::new();
        let json_schema = json!({
            "title": "User",
            "type": "object",
            "properties": {
                "id": {
                    "type": "integer"
                },
                "name": {
                    "type": "string"
                },
                "email": {
                    "type": "string"
                }
            }
        });

        let result = parser.infer_from_json(&json_schema);
        assert!(result.is_ok());

        let schema = result.unwrap();
        assert_eq!(schema.name, "User");
        assert_eq!(schema.fields.len(), 3);
    }

    #[test]
    fn test_pattern_matching() {
        let parser = SchemaParser::new();
        
        // 测试ID字段识别
        let id_type = parser.infer_data_type("user_id", &json!({})).unwrap();
        match id_type {
            DataType::Integer { .. } => {},
            _ => panic!("Expected Integer type for ID field"),
        }

        // 测试邮箱字段识别
        let email_type = parser.infer_data_type("user_email", &json!({})).unwrap();
        match email_type {
            DataType::Email => {},
            _ => panic!("Expected Email type for email field"),
        }
    }

    #[test]
    fn test_database_type_mapping() {
        let parser = SchemaParser::new();
        
        let varchar_type = parser.map_database_type("VARCHAR(255)").unwrap();
        match varchar_type {
            DataType::String { max_length: Some(255) } => {},
            _ => panic!("Expected String type with max_length for VARCHAR"),
        }

        let int_type = parser.map_database_type("INTEGER").unwrap();
        match int_type {
            DataType::Integer { .. } => {},
            _ => panic!("Expected Integer type for INTEGER"),
        }
    }

    #[test]
    fn test_custom_type_mapping() {
        let mut parser = SchemaParser::new();
        
        parser.add_type_mapping(
            "custom_type".to_string(),
            DataType::Custom {
                type_name: "CustomType".to_string(),
                generator: "custom_generator".to_string(),
            }
        );

        let custom_type = parser.map_database_type("custom_type").unwrap();
        match custom_type {
            DataType::Custom { type_name, .. } => {
                assert_eq!(type_name, "CustomType");
            },
            _ => panic!("Expected Custom type"),
        }
    }

    #[test]
    fn test_pattern_rule_priority() {
        let mut parser = SchemaParser::new();
        
        // 添加高优先级规则
        parser.add_pattern_rule(r"(?i)^special_.*$", DataType::Uuid, 200).unwrap();
        
        let special_type = parser.infer_data_type("special_id", &json!({})).unwrap();
        match special_type {
            DataType::Uuid => {},
            _ => panic!("Expected Uuid type for special field with high priority rule"),
        }
    }
}